package org.tulkas.log;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;
import java.util.logging.Level;

import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MarkerIgnoringBase;
import org.slf4j.helpers.MessageFormatter;

/**
 * @author <a href="mailto:tulkas.web@gmail.com">Tulkas</a>
 *
 */
public class TulkasLogger extends MarkerIgnoringBase {
	private static final long serialVersionUID = -1539107131739194704L;

	public TulkasLogger(String name) {
		this.name = name;
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#debug(java.lang.String)
	 */
	public void debug(String msg) {
		log(LogRecord.LEVEL_DEBUG, msg, null);
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#debug(java.lang.String, java.lang.Object)
	 */
	public void debug(String format, Object arg) {
		FormattingTuple ft = MessageFormatter.format(format, arg);
		debug(ft.getMessage());
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#debug(java.lang.String, java.lang.Object[])
	 */
	public void debug(String format, Object[] argArray) {
		FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
		debug(ft.getMessage(), ft.getThrowable());
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#debug(java.lang.String, java.lang.Throwable)
	 */
	public void debug(String msg, Throwable t) {
		log(LogRecord.LEVEL_DEBUG, msg, t);
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#debug(java.lang.String, java.lang.Object, java.lang.Object)
	 */
	public void debug(String format, Object arg1, Object arg2) {
		FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
		debug(ft.getMessage(), ft.getThrowable());
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#error(java.lang.String)
	 */
	public void error(String msg) {
		log(LogRecord.LEVEL_ERROR, msg, null);
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#error(java.lang.String, java.lang.Object)
	 */
	public void error(String format, Object arg) {
		FormattingTuple ft = MessageFormatter.format(format, arg);
		error(ft.getMessage(), ft.getThrowable());
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#error(java.lang.String, java.lang.Object[])
	 */
	public void error(String format, Object[] argArray) {
		FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
		error(ft.getMessage(), ft.getThrowable());
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#error(java.lang.String, java.lang.Throwable)
	 */
	public void error(String msg, Throwable t) {
		log(LogRecord.LEVEL_ERROR, msg, t);
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#error(java.lang.String, java.lang.Object, java.lang.Object)
	 */
	public void error(String format, Object arg1, Object arg2) {
		FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
		error(ft.getMessage(), ft.getThrowable());
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#info(java.lang.String)
	 */
	public void info(String msg) {
		log(LogRecord.LEVEL_INFO, msg, null);
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#info(java.lang.String, java.lang.Object)
	 */
	public void info(String format, Object arg) {
		FormattingTuple ft = MessageFormatter.format(format, arg);
		info(ft.getMessage(), ft.getThrowable());
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#info(java.lang.String, java.lang.Object[])
	 */
	public void info(String format, Object[] argArray) {
		FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
		info(ft.getMessage(), ft.getThrowable());
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#info(java.lang.String, java.lang.Throwable)
	 */
	public void info(String msg, Throwable t) {
		log(LogRecord.LEVEL_INFO, msg, t);
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#info(java.lang.String, java.lang.Object, java.lang.Object)
	 */
	public void info(String format, Object arg1, Object arg2) {
		FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
		info(ft.getMessage(), ft.getThrowable());
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#isDebugEnabled()
	 */
	public boolean isDebugEnabled() {
		return true;
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#isErrorEnabled()
	 */
	public boolean isErrorEnabled() {
		return true;
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#isInfoEnabled()
	 */
	public boolean isInfoEnabled() {
		return true;
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#isTraceEnabled()
	 */
	public boolean isTraceEnabled() {
		return true;
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#isWarnEnabled()
	 */
	public boolean isWarnEnabled() {
		return true;
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#trace(java.lang.String)
	 */
	public void trace(String msg) {
		log(LogRecord.LEVEL_TRACE, msg, null);
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#trace(java.lang.String, java.lang.Object)
	 */
	public void trace(String format, Object arg) {
		FormattingTuple ft = MessageFormatter.format(format, arg);
		trace(ft.getMessage(), ft.getThrowable());
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#trace(java.lang.String, java.lang.Object[])
	 */
	public void trace(String format, Object[] argArray) {
		FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
		trace(ft.getMessage(), ft.getThrowable());
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#trace(java.lang.String, java.lang.Throwable)
	 */
	public void trace(String msg, Throwable t) {
		log(LogRecord.LEVEL_TRACE, msg, t);
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#trace(java.lang.String, java.lang.Object, java.lang.Object)
	 */
	public void trace(String format, Object arg1, Object arg2) {
		FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
		trace(ft.getMessage(), ft.getThrowable());
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#warn(java.lang.String)
	 */
	public void warn(String msg) {
		log(LogRecord.LEVEL_WARN, msg, null);
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#warn(java.lang.String, java.lang.Object)
	 */
	public void warn(String format, Object arg) {
		FormattingTuple ft = MessageFormatter.format(format, arg);
		warn(ft.getMessage(), ft.getThrowable());
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#warn(java.lang.String, java.lang.Object[])
	 */
	public void warn(String format, Object[] argArray) {
		FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
		warn(ft.getMessage(), ft.getThrowable());
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#warn(java.lang.String, java.lang.Throwable)
	 */
	public void warn(String msg, Throwable t) {
		log(LogRecord.LEVEL_WARN, msg, t);
	}

	/* (non-Javadoc)
	 * @see org.slf4j.Logger#warn(java.lang.String, java.lang.Object, java.lang.Object)
	 */
	public void warn(String format, Object arg1, Object arg2) {
		FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
		warn(ft.getMessage(), ft.getThrowable());
	}

//	protected int getLogLevel() {
//		String type = null;
//		Thread thread = Thread.currentThread();
//		if (thread instanceof ILogTypedThread) {
//			type = ((ILogTypedThread) thread).getLogType();
//		}
//		return LogManager.getInstance().getLoggerLevel(type);
//	}

	private java.util.logging.Level getJdkLogLevel(int level) {
		switch (level) {
		case 1:
			return Level.SEVERE;
		case 2:
			return Level.WARNING;
		case 3:
			return Level.INFO;
		case 4:
			return Level.FINE;
		case 5:
			return Level.FINEST;
		default:
			return Level.OFF;
		}
	}

	protected void log(int level, String message, Throwable throwable) {
//		LogManager mgr = LogManager.getInstance();
//		if (!mgr.isSystemInitialized() || mgr.isForceJdkLogger()) {
			java.util.logging.Logger logger = java.util.logging.Logger
					.getLogger(this.getName());
			Level jdkLevel = getJdkLogLevel(level);
			if (logger.isLoggable(jdkLevel)) {
				logger.log(jdkLevel, message, throwable);
			}
//		}

//		if (mgr.isInitialized() && !mgr.isForceJdkLogger()
//				&& getLogLevel() >= level) {
//			LogRecord record = new LogRecord();
//			record.setLevel(level);
//			record.setName(getName());
//			record.setMessage(message);
//			record.setThreadName(Thread.currentThread().getName());
//			record.setTime(new Date());
//			if (Thread.currentThread() instanceof ILogTypedThread) {
//				ILogTypedThread typedThread = (ILogTypedThread) Thread
//						.currentThread();
//				record.setLogType(typedThread.getLogType());
//			}
//			if (throwable != null) {
//				StringWriter writer = new StringWriter();
//				throwable.printStackTrace(new PrintWriter(writer));
//				record.setExceptionStackTrace(writer.toString());
//			}
//			LogManager.getInstance().log(record);
//		}
	}
}
